﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
// add
using FormBaseLib;

namespace FormBase
{
    public partial class FMNT0010 : Form, IEntryAction
    {
        CDatasetKeyValue mCDataSet = new CDatasetKeyValue();
        delegate void ShowMsgEventHandler(string sMsg, Color color1);
        CBase mLastError = new CBase();
        public string msProgramID { get; private set; }
        public enumEntryMode mEntryMode { get; private set; }
        public FMNT0010()
        {
            InitializeComponent();
        }

        private void FMNT0010_Load(object sender, EventArgs e)
        {
            txtNote.Text = "1. 這是單機單工版樣板. \r\n2.整個資料庫存在記憶體中, 若沒有存檔, 則離開程式以後資料就消失.";
            msProgramID = "FMNT0010";
            mCDataSet.msFile = string.Format(@"{0}\{1}.xml", CProject.mApp.msPathData, msProgramID);
            if (System.IO.File.Exists(mCDataSet.msFile))
                btnLoadDB.Enabled = true;
            else
            {
                CProject.mApp.PopupError(string.Format(@"File does not exist. file={0}.", mCDataSet.msFile));
                btnLoadDB.Enabled = false;
            }

            cboSortOrder.Items.Clear();
            cboSortOrder.Items.AddRange(new string[]{"Key", "Value, Key", "Key(desc)+Value"});
            cboSortOrder.SelectedIndex = 0;

            EntryInit();
            myShowAfterFormLoad(false);

        }
        public void ShowMsg(string sMsg)
        {
            Invoke(new ShowMsgEventHandler(OnShowMsg), new object[] { sMsg, SystemColors.ControlText });
        }
        public void ShowMsgError(string sMsg)
        {
            Invoke(new ShowMsgEventHandler(OnShowMsg), new object[] { sMsg, Color.Red });
        }

        private void OnShowMsg(string sMsg, Color color1)
        {
            lblStatus.Text = sMsg;
            if (lblStatus.ForeColor != color1)
                lblStatus.ForeColor = color1;
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {

        }
        private void SearchClear()
        {
            txtSearchKey.Clear();
            txtSearchValue.Clear();
            cboSortOrder.SelectedIndex = 0;
            dgvData.DataSource = null;
            //dgvData.Rows.Clear(); not applicable to dataview
        }
        private void SearchSample()
        {
            txtSearchKey.Text = "K2*";
            txtSearchValue.Text = "V2*";
            EntrySearch();
        }
        private void BrowseRefresh()
        {
            // use same last search criteria!
            EntrySearch();
        }
        private void EntrySearch()
        {
            StringBuilder sb = new StringBuilder();
            sb.Length = 0;
            if (!string.IsNullOrWhiteSpace(txtSearchKey.Text))
                sb.AppendFormat("and FKey LIKE '{0}'", txtSearchKey.Text);
            if (!string.IsNullOrWhiteSpace(txtSearchValue.Text))
                sb.AppendFormat("and FValue LIKE '{0}'", txtSearchValue.Text);

            if (sb.Length > 0)
                sb.Remove(0, 4);

            //string sExpr = "FKey LIKE 'K2*' and FValue LIKE 'V2*'";
            string sExpr = sb.ToString();
            string sSort;
            switch(cboSortOrder.SelectedIndex)
            {
                case 1:
                    sSort = "FValue, FKey";
                    break;

                case 2:
                    sSort = "FKey desc, FValue";
                    break;

                default:
                    sSort = "FKey";
                    break;
            }

            //mDataView = mCDataSet.mTable.DefaultView;
            //mDataView.RowFilter = sExpr;
            //mDataView.Sort = sSort;
            //dgvData.DataSource = mCDataSet.mDataView;
            //mDataView = mCDataSet.SearchDataView(sExpr, sSort);
            if (mCDataSet.SearchDataView(sExpr, sSort))
            {
                dgvData.DataSource = mCDataSet.mDataView;
                ShowSearchCount();
            }
        }
        void ShowSearchCount()
        {
            //lblCount.Text = dv.Count.ToString();
            lblCount.Text = mCDataSet.mDataView.Count.ToString();
        }
        public void EntryClear()
        {
            txtFKey.Text = string.Empty;
            txtFValue.Text = string.Empty;
        }
        public void EntryLoad()
        {
            if (!mCDataSet.Load())
            {
                ShowMsgError(mCDataSet.msLastError);
                return;
            }
            //mCDataSet.RowInit();
            EntryClear();
        }
        void EntryInit()
        {
            EntryClear();
            EntryShow(enumEntryMode.Add, "Init OK. Ready to input.");
        }
        public bool EntryUpdate()
        {
            if (!EntryCheckForUpdate())
                return false;

            if (!EntryFlush())
                return false;

            if (!mCDataSet.RowUpdate(true))
            {
                CProject.mApp.PopupError(mCDataSet.msLastError);
                return false;
            }
            CProject.mApp.PopupMsg("Update OK");
            EntryNew();
            return true;
        }
        public bool EntryCheckPrimaryKey()
        {
            if (String.IsNullOrWhiteSpace(txtFKey.Text))
            {
                ShowMsgError("Please input key field.");
                return false;
            }
            return true;
        }
        public bool EntryCheckForCreate()
        {
            if (!EntryCheckPrimaryKey())
                return false;

            if (String.IsNullOrWhiteSpace(txtFValue.Text))
            {
                ShowMsgError("Please input value field.");
                return false;
            }
            return true;
        }
        public bool EntryCreate()
        {
            if (!EntryCheckForCreate())
                return false;

            if (!EntryFlush())
                return false;

            if (!mCDataSet.RowCreate(true))
            {
                ShowMsgError(mCDataSet.msLastError);
                return false;
            }

            CProject.mApp.PopupMsg("Add OK");
            EntryNew();
            return true;
        }

        public bool EntryRead()
        {
            if (!EntryCheckForRead())
                return false;

            mCDataSet.mRow.FKey = txtFindKey.Text.TrimEnd();
            if (!mCDataSet.RowFindPrimaryKey())
            {
                ShowMsgError("Can't find key=" + mCDataSet.mRow.FKey);
                return false;
            }
            if (!mCDataSet.RowRead(true))
            {
                ShowMsgError("Can't select key=" + mCDataSet.mRow.FKey);
                return false;
            }
            
            //if (!mCDataSet.RowFetch())
            //{
            //    ShowMsgError("Can't fetch row.");
            //    return;
            //}
            //txtFKey.Text = mCDataSet.mRow.FKey;
            //txtFValue.Text = mCDataSet.mRow.FValue;
            if (!EntryFetch())
                return false;

            EntryShow(enumEntryMode.Update, "Data is found. Ready for update.");
            return true;
        }
        public void EntryShow(enumEntryMode iMode, string sMsg)
        {
            mEntryMode = iMode;
            lblMode.Text = iMode.ToString();
            ShowMsg(sMsg);
            switch (iMode)
            {
                case enumEntryMode.Add:
                    //txtFKey.Text = mCDataSet.mRow.FKey;
                    //txtFValue.Text = mCDataSet.mRow.FValue;
                    txtFKey.Enabled = true;
                  
                    groupBoxEntry.Enabled = true;
                    btnAdd.Enabled = true;
                    btnUpdate.Enabled = false;
                    btnDelete.Enabled = false;
                    btnRestore.Enabled = true;
                    btnCopy.Enabled = false;
                    break;
                case enumEntryMode.Update:
                    txtFKey.Text = mCDataSet.mRow.FKey;
                    txtFKey.Enabled = false;
                    txtFValue.Text = mCDataSet.mRow.FValue;

                    groupBoxEntry.Enabled = true;
                    btnAdd.Enabled = false;
                    btnUpdate.Enabled = true;
                    btnDelete.Enabled = true;
                    btnRestore.Enabled = true;
                    btnCopy.Enabled = true;
                    break;
                default:
                    mEntryMode = enumEntryMode.Init;
                    groupBoxEntry.Enabled = false;
                    btnAdd.Enabled = false;
                    btnUpdate.Enabled = false;
                    btnDelete.Enabled = false;
                    btnRestore.Enabled = false;
                    btnCopy.Enabled = false;
                    break;
            }
        }
        public bool EntryCheckForUpdate()
        {
            if (!EntryCheckPrimaryKey())
                return false;

            return true;
        }
        public bool EntryCheckForDelete()
        {
            if (!EntryCheckPrimaryKey())
                return false;

            return true;
        }
        public bool EntryCheckForRead()
        {
            if (String.IsNullOrEmpty(txtFindKey.Text))
            {
                ShowMsgError("Please input key to find.");
                return false;
            }
            if (txtFindKey.Text.TrimEnd().Length < 1)
            {
                ShowMsgError("Please input key to find without blank.");
                return false;
            }
            return true;
        }
        public bool EntryDelete()
        {
            if (!EntryCheckForDelete())
                return false;

            mCDataSet.mRow.FKey = txtFKey.Text;
            if (!mCDataSet.RowDelete(true))
            {
                ShowMsgError(mCDataSet.msLastError);
                return false;
            }
            CProject.mApp.PopupMsg("Delete OK");
            EntryNew();
            return true;
        }
        void EntryNew()
        {
            EntryClear();
            EntryShow(enumEntryMode.Add, "Please input new entry.");
        }
        void EntryCopy()
        {
            switch (mEntryMode)
            {
                case enumEntryMode.Update:
                    EntryShow(enumEntryMode.Add, "Record is copied for add.");
                    return;
                case enumEntryMode.View:
                    EntryShow(enumEntryMode.Add, "Record is copied for add.");
                    return;
                default:
                    ShowMsg("Only can copy data in update or view mode.");
                    return;
            }
           

        }
        public bool EntryFlush()
        {
            mCDataSet.mRow.FKey = txtFKey.Text.TrimEnd();
            mCDataSet.mRow.FValue = txtFValue.Text.TrimEnd();
            return true;
        }
        public bool EntryFetch()
        {
            txtFKey.Text = mCDataSet.mRow.FKey;
            txtFValue.Text = mCDataSet.mRow.FValue;
            return true;
        }
        public bool EntryRestore()
        {
            if (!mCDataSet.RowRestore())
            {
                ShowMsgError(mCDataSet.msLastError);
                return false;
            }
            if (!EntryFetch())
                return false;

            ShowMsg("Entry restored.");
            return true;
        }
        bool myAddRow(string sKey, string sValue)
        {
            mCDataSet.mRow.FKey = sKey;
            mCDataSet.mRow.FValue = sValue;
            return mCDataSet.RowCreate(true);
        }

        void myCreateDB() 
        {
            myAddRow("k3", "v3");
            myAddRow("k3", "v3");
            myAddRow("k2", "v2");
            myAddRow("k23", "v23");
            myAddRow("k22", "v22");
            myAddRow("k21", "v21");
            myAddRow("k5", "v5");
            myAddRow("k4", "v4");
            myAddRow("k1", "v1");
            if (!myAddRow("k1", "v1"))
            {
                ShowMsgError(mCDataSet.msLastError);
                return;
            }
            mySaveDB();
            myLoadDB();
        }
        void myShowAfterFormLoad(bool bOpen)
        {
            groupBoxFind.Enabled = bOpen;
            //groupBoxEntry.Enabled = bOpen;
            groupBoxSearch.Enabled = bOpen;
            groupBoxBrowse.Enabled = bOpen;
            btnSaveDB.Enabled = bOpen;
        }
        void myLoadDB()
        {
            EntryLoad();
            //mDataView = mCDataSet.mTable.DefaultView;
            //mDataView.RowFilter = string.Empty;
            //mDataView.Sort = string.Empty;
            if (mCDataSet.SearchDataView(string.Empty, string.Empty))
                dgvData.DataSource = mCDataSet.mDataView;

            ShowSearchCount();

            myShowAfterFormLoad(true);

        }

        void mySaveDB()
        {
            if (mCDataSet.Save())
                ShowMsg("OK");
            else
                ShowMsgError(mCDataSet.msLastError);
        }
        private void dgvData_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            ShowMsgError(e.Exception.Message);
        }


        private void btnCreateDB_Click(object sender, EventArgs e)
        {
            myCreateDB();

        }

        private void btnLoadDB_Click(object sender, EventArgs e)
        {
            myLoadDB();
        }

        private void btnSaveDB_Click(object sender, EventArgs e)
        {
            mySaveDB();
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            EntrySearch();
        }

        private void btnSearchClear_Click(object sender, EventArgs e)
        {
            SearchClear();
        }

        private void btnSearchSample_Click(object sender, EventArgs e)
        {
            SearchSample();
        }

        private void btnBrowseRefresh_Click(object sender, EventArgs e)
        {
            EntrySearch();

        }


        private void btnAdd_Click(object sender, EventArgs e)
        {
            EntryCreate();
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            EntryUpdate();
        }

        private void btnRestore_Click(object sender, EventArgs e)
        {
            EntryRestore();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            EntryDelete();
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            EntryCopy();
        }

        private void btnNewInFind_Click(object sender, EventArgs e)
        {
            EntryNew();
           
        }

        private void btnReadSample_Click(object sender, EventArgs e)
        {
            txtFindKey.Text = "k21";
            EntryRead();
        }

        private void btnRead_Click(object sender, EventArgs e)
        {
            EntryRead();
        }




    }
}
